package com.xquant.common.engine.xPP.request.scene;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.xquant.common.engine.xPP.request.CalcEngineParam;
import com.xquant.common.engine.xPP.request.CalcPricingParam;
import com.xquant.common.engine.xPP.request.Instrument;
import com.xquant.common.engine.xPP.request.instrument.IProduct;
import com.xquant.common.engine.xPP.request.instrument.ProductFactory;
import com.xquant.common.engine.xPP.request.instrument.SceneInstrument;

import java.util.ArrayList;
import java.util.List;

/**
 * @author B946
 * @date 26/09/2020 11:53
 * @description:
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
public class CalcSceneQuoteEngineParam extends CalcEngineParam {

    private List<SceneFactor> quoteParam;

    public List<SceneFactor> getQuoteParam() {
        return quoteParam;
    }

    public void setQuoteParam(List<SceneFactor> quoteParam) {
        this.quoteParam = quoteParam;
    }


    public List<SceneCalcEngineParam> buildCalcEngineParam(){
        List<SceneCalcEngineParam> calcEngineParams = new ArrayList<>();
        List<SceneInstrument> sceneInstruments = buildInstruments();
        for (SceneInstrument sceneInstrument:sceneInstruments) {
            CalcEngineParam calcEngineParam = new CalcEngineParam();
            calcEngineParam.setCalcPricingParam(cloneCalcPricingParam(this.getCalcPricingParam()));
            calcEngineParam.setRequestCode(this.getRequestCode());
            calcEngineParam.setCustomPricingParam(this.getCustomPricingParam());
            calcEngineParam.setUnderlyingMarkets(this.getUnderlyingMarkets());
            calcEngineParam.setInstrument(sceneInstrument.getInstrument());
            SceneCalcEngineParam sceneCalcEngineParam = new SceneCalcEngineParam(calcEngineParam,sceneInstrument.getFactors());
            calcEngineParams.add(sceneCalcEngineParam);
        }
        return calcEngineParams;
    }

    /**
     * 根据报价因子组合金融工具
     * @return
     */
    public List<SceneInstrument> buildInstruments(){
        JSONArray customLegs = getInstrument().getTermsheet().getJSONArray("customLegs");
        String productType = customLegs.getJSONObject(0).getString("productType");
        IProduct product = ProductFactory.getProduct(productType);
        List<List<Factor>> factorsList = FactorUtils.resovleFactor(quoteParam);
        List<SceneInstrument> list = new ArrayList<>();
        for(Factor factor:factorsList.get(0)){
            Instrument instrument = cloneInstrument(this.getInstrument());
            product.buildInstrument(instrument, factor);
            SceneInstrument sceneInstrument = new SceneInstrument(instrument);
            sceneInstrument.addFactor(factor);
            list.add(sceneInstrument);
        }
        List<SceneInstrument> list2 = new ArrayList<>();
        if(factorsList.size() == 2 && factorsList.get(1) != null){
            for(SceneInstrument sceneInstrument : list){
                for(Factor factor : factorsList.get(1)){
                    SceneInstrument sceneInstrument1 = new SceneInstrument(cloneInstrument(sceneInstrument.getInstrument()));
                    sceneInstrument1.addFactors(sceneInstrument.getFactors());
                    product.buildInstrument(sceneInstrument1.getInstrument(), factor);
                    sceneInstrument1.addFactor(factor);
                    list2.add(sceneInstrument1);
                }
            }
        }else{
            list2.addAll(list);
        }
        return list2;
    }

    /**
     *
     * @return
     */
    public List<Instrument> buildInstruments2(){
        JSONArray customLegs = getInstrument().getTermsheet().getJSONArray("customLegs");
        String productType = customLegs.getJSONObject(0).getString("productType");
        IProduct product = ProductFactory.getProduct(productType);
        List<List<Factor>> factorsList = FactorUtils.resovleFactor(quoteParam);
        List<Instrument> list = new ArrayList<>();
        for(List<Factor> factors:factorsList){
            for(Factor factor:factors){
                Instrument instrument = cloneInstrument(this.getInstrument());
                product.buildInstrument(instrument, factor);
                list.add(instrument);
            }
        }

        return list;
    }


    public Instrument cloneInstrument(Instrument instrument){
        return JSON.parseObject(JSON.toJSONString(instrument),Instrument.class);
    }

    public CalcPricingParam cloneCalcPricingParam(CalcPricingParam calcPricingParam){
        return JSON.parseObject(JSON.toJSONString(calcPricingParam),CalcPricingParam.class);
    }






}
